#include "Elemento.h"
#include <iostream>
#include <sstream>
#include "UnidadLogica.h"

Elemento::Elemento(double x, double y, double ancho, double alto,
		string pathImagen) :
		Redimensionable(x, y, ancho, alto) {
	this->pathImagen = pathImagen;
	this->anguloRotacion = 0;
	this->texturaElemento = NULL;
	this->frameActual = 0;
	this->cantFrames = 0;
	this->idUnionesEngranajes=NULL;
	this->pelotaAdentro = false;
	cout << "creo elemento de tipo: " << this->pathImagen << " con id: "
			<< idElemento << endl;
	this->esFijo = false;
	this->visitadoEliminar =false;
	this->yaVisiteParaCrear = false;
	this->entidadFisica = NULL;
}

Elemento::~Elemento() {
	SDL_DestroyTexture(texturaElemento);
}

void Elemento::rotar(SDL_Renderer *renderer, double grados) {
	cout << "Estoy tratando de rotar" << endl;
}

const string& Elemento::getTipo() const {
	return tipo;
}

void Elemento::setTipo(const string& tipo) {
	this->tipo = tipo;
}

double Elemento::getAnguloRotacion() const {
	return anguloRotacion;
}

void Elemento::setAnguloRotacion(double ang) {
	anguloRotacion = ang;
}

string Elemento::getPathImagen() {
	return this->pathImagen;
}

void Elemento::setPathImagen(string path) {
	this->pathImagen = path;
}

void Elemento::dibujar(double x, double y, double largo, double ancho,
		SDL_Renderer* renderer) {
	if (texturaElemento == NULL) {
	//	cout << "Setee el path en: " << pathImagen << endl;

		surfaceElemento = IMG_Load(this->pathImagen.c_str());
		texturaElemento = SDL_CreateTextureFromSurface(renderer,
				surfaceElemento);

		if (texturaElemento == NULL) {
			std::cout << "SDL_CreateTextureFromSurface Error: "
					<< SDL_GetError() << std::endl;
			return;
		}
	}
	UnidadLogica* unidadLogica = UnidadLogica::obtenerInstancia();

	pair<double, double> conversionAnchoyAlto = unidadLogica->convertirULAPixel(
			this->getAncho(), this->getAlto());

	pair<double, double> conversionPosXeY = unidadLogica->convertirULAPixel(
			this->getX(), this->getY());
	SDL_Rect sdlRect;
	sdlRect.w = conversionAnchoyAlto.first;
	sdlRect.h = conversionAnchoyAlto.second;
	sdlRect.x = conversionPosXeY.first;
	sdlRect.y = conversionPosXeY.second;

	SDL_Point centro;
	centro.x = (sdlRect.w / 2);
	centro.y = (sdlRect.h / 2);
	SDL_RenderCopyEx(renderer, texturaElemento, NULL, &sdlRect,
			this->getAnguloRotacion(), &centro, SDL_FLIP_NONE);

	anchoPixeles = sdlRect.w;
	altoPixeles = sdlRect.h;

}

void Elemento::actualizarValoresFisicos() {

	this->x = this->entidadFisica->obtenerPosicionX() - this->getAncho()/2;
	this->y = 100 - this->entidadFisica->obtenerPosicionY() - this->getAlto()/2;
	//cout<<"IMPRIMO VALORES LUEGO DE SIMULACION:"<<this->getTipo()<<" "<<this->x<<" ; "<<this->y<<" ang:"<< ((this->entidadFisica->obtenerAngulo())*180/b2_pi)<<endl;
	//cout<<"vel angular: "<<this->getEntidadFisica()->obtenerVelocidadAngular()<<endl;
	this->anguloRotacion = 360- ((this->entidadFisica->obtenerAngulo())*180/b2_pi);
	this->actualizarReferencias();
	this->actualizarImagen();

}

void Elemento::setElementoFisico(EntidadFisica* entidadfisica) {
	this->entidadFisica = entidadfisica;
}

bool Elemento::aceptaEngranaje() {
	return false;
}

bool Elemento::aceptaSoga() {
	return false;
}

void Elemento::agregarEngranaje(Elemento* elemento) {
	return;
}
void Elemento::eliminarEngranaje() {
	return;
}

void Elemento::eliminarEngranajeDeLista(Elemento* elemento){
	return;
}


Elemento* Elemento::obtenerEngranaje() {
	return NULL;
}

bool Elemento::aceptaCorrea() {
	return false;
}
void Elemento::eliminarCorrea() {
	return;
}
void Elemento::agregarCorreaInicial(Elemento* correa) {
	return;
}
void Elemento::agregarCorreaFinal(Elemento* correa) {
	return;
}

void Elemento::agregarSogaInicial(Elemento* elemento) {
	return;
}
void Elemento::agregarSogaFinal(Elemento* elemento) {
	return;
}
void Elemento::eliminarSoga(Elemento* soga) {
	return;
}

bool Elemento::chequearIngresoCinta(Elemento* elemento){
	return false;
}


bool Elemento::entraEnCinta(list<Elemento*>*lista){

	list<Elemento*>::iterator itLista = lista->begin();
	for(; itLista != lista->end(); itLista++){

		Elemento* elemento = (*itLista);
		if(elemento->getTipo() == "cinta"){
			double x,y,ancho,alto;
			x = elemento->getX() + elemento->getAncho()*PROPORCION_TRANSPARENCIA_CINTA_X;
			y = elemento->getY() + elemento->getAlto()*PROPORCION_TRANSPARENCIA_CINTA_Y;
			ancho = elemento->getAncho() * PROPORCION_TRANSPARENCIA_CINTA_ANCHO;
			alto = elemento->getAlto() * PROPORCION_TRANSPARENCIA_CINTA_ALTO;

			if ((this->getX() >= x) && (this->getX() <= (x + ancho))
					&& (this->getY() >= y) && (this->getY() <= (y + alto))){
				return this->chequearIngresoCinta(elemento);
			}
		}
	}
	return true;

}

bool Elemento::agregaEnVacio() {
	return true;
}

void Elemento::mover(double x, double y) {
	double centroX = x - this->getAncho() / 2;
	double centroY = y - this->getAlto() / 2;
	this->setX(centroX);
	this->setY(centroY);
}

void Elemento::superponer(Elemento* elemento) {
	return;
}
/*
 * devuelve 0: No hace nada
 * devuelve 1: Se superpone bien: Verde
 * devuelve 2: Se superpone mal: Rojo
 *
 */
int Elemento::seSuperpone(Elemento* elemento) {
	return 2;
}

void Elemento::rotar(double angulo) {
	this->anguloRotacion = angulo;
}

bool Elemento::dejarEnCanvas(double x, double y) {
	return true;
}

void Elemento::jointearElemento(b2World* world) {
}

bool Elemento::tieneVertices() {
	return true;
}

void Elemento::setPosicionInicial(double x, double y) {
	return;
}
void Elemento::setPosicionFinal(double x, double y) {
	return;
}

void Elemento::eliminarReferencias(list<Elemento*>* elementosCanvas) {
	return;
}

pair<Elemento*, Elemento*> Elemento::obtenerExtremos() {
	pair<Elemento*, Elemento*> extremos;
	extremos.first = NULL;
	extremos.second = NULL;
	return extremos;
}

//pair<Elemento*, Elemento*> Elemento::obtenerExtremosSoga() {
//	pair<Elemento*, Elemento*> extremos;
//	extremos.first = NULL;
//	extremos.second = NULL;
//	return extremos;
//}
//
//pair<Elemento*, Elemento*> Elemento::obtenerExtremosCorrea() {
//	pair<Elemento*, Elemento*> extremos;
//	extremos.first = NULL;
//	extremos.second = NULL;
//	return extremos;
//}
//
//pair<Elemento*, Elemento*> Elemento::obtenerExtremosBalancin() {
//	pair<Elemento*, Elemento*> extremos;
//	extremos.first = NULL;
//	extremos.second = NULL;
//	return extremos;
//}

pair<double, double> Elemento::getPosicionInicial() {
	pair<double, double> posicion;
	posicion.first = 0;
	posicion.second = 0;
	return posicion;
}
pair<double, double> Elemento::getPosicionFinal() {
	pair<double, double> posicion;
	posicion.first = 0;
	posicion.second = 0;
	return posicion;
}

int Elemento::getIdElemento() {
	return this->idElemento;
}

bool Elemento::esBasico() {
	return true;
}

void Elemento::setIdElemento(int id) {
	this->idElemento = id;
}

void Elemento::setIdElementoUnion1(int id) {
	this->idElementoUnion1 = id;
}
void Elemento::setIdElementoUnion2(int id) {
	this->idElementoUnion2 = id;
}
int Elemento::getIdElementoUnion1() {
	return this->idElementoUnion1;
}
int Elemento::getIdElementoUnion2() {
	return this->idElementoUnion2;
}

bool Elemento::esAnimable() {
	return false;
}

void Elemento::animar() {
	cout << "animo a: " << this->getTipo() << "frame actual: " << frameActual<< endl;
	stringstream ss;
	ss << "img/" << this->getTipo() << "Anim" << this->frameActual << ".png";
	string pathImagenAnimacion = ss.str();

	if (this->frameActual == this->cantFrames)
		this->frameActual = 0;

	this->frameActual++;
	cout << "nueva imagen animacon: " << pathImagenAnimacion << endl;
	this->setPathImagen(pathImagenAnimacion);
	SDL_FreeSurface(surfaceElemento);
	SDL_DestroyTexture(texturaElemento);
	surfaceElemento = NULL;
	texturaElemento = NULL;
}
void Elemento::actualizarReferencias(){
	return;
}

bool Elemento::sogaEnPosInicial(){
	return false;
}
bool Elemento::sogaEnPosFinal(){
	return false;
}

bool Elemento::engranajeEnLista(Elemento* elemento){
	return false;
}


void Elemento::setListaIdUnionesEngranajes(list<string>* lista){
	this->idUnionesEngranajes = lista;
}

list<string>* Elemento::getListaIdUnionesEngranajes(){
	return this->idUnionesEngranajes;
}

void Elemento::actualizarImagen(){

}

bool Elemento::fueVisitadoEnEliminar(){
	return this->visitadoEliminar;
}

void Elemento::setFueVisitado(bool valorVisitado){
	this->visitadoEliminar = valorVisitado;
}

bool Elemento::fueVisitadoEnCrear(){
	return this->yaVisiteParaCrear;
}

void Elemento::setFueVisitadoCrear(bool valorVisitado){
	this->yaVisiteParaCrear = valorVisitado;
}


void Elemento::eliminarImagenElemento(){
	SDL_FreeSurface(this->surfaceElemento);
	SDL_DestroyTexture(this->texturaElemento);
	this->surfaceElemento = NULL;
	this->texturaElemento = NULL;
}


void Elemento::actualizarSonido(){

}


